<?php


namespace app\system\service;

class MenuService
{
	public static function getlist($options = [])
	{
		$lists = \think\Db::name("system_admin_menu")->field(["id", "type", "system", "pid", "name", "sort", "icon", "uri", "disable", "show"])->order(["sort" => "desc", "type" => "asc"])->select();
		$pids = \think\Db::name("system_admin_menu")->where(["type" => 1])->column("pid");
		foreach ($lists as $k => $v) {
			$lists[$k]["type_str"] = $v["type"] == 1 ? "菜单" : "权限";
			$lists[$k]["open"] = in_array($v["id"], $pids);
			$lists[$k]["disable"] = \intval($lists[$k]["disable"]);
			$lists[$k]["show"] = \intval($lists[$k]["show"]);
		}
		$lists = (new \app\common\system\System())->admin_menu_plug_filter($lists, "system_menu_id", true, true);
		$data = linear_to_tree($lists);
		return ["code" => \app\system\model\Code::success, "data" => $data];
	}
	public static function getinfo($options)
	{
		$data = \think\Db::name("system_admin_menu")->where(["id" => $options["id"]])->field(["id", "type", "system", "pid", "name", "sort", "icon", "uri", "disable", "show"])->find();
		if (empty($data)) {
			return ["code" => \app\system\model\Code::fail, "msg" => "ID不存在"];
		}
		return ["code" => \app\system\model\Code::success, "data" => $data];
	}
	public static function choose($options = [])
	{
		$where[] = ["type", "=", 1];
		if ($options["isall"]) {
			$where = [];
		}
		$lists = \think\Db::name("system_admin_menu")->field(["id", "type", "pid", "name", "uri"])->where($where)->select();
		if ($options["id"]) {
			$remove_ids = self::getChildIds($lists, $options["id"]);
			$remove_ids[] = $options["id"];
			foreach ($lists as $key => $row) {
				if (in_array($row["id"], $remove_ids)) {
					unset($lists[$key]);
				}
			}
			$lists = array_values($lists);
		}
		$data = multilevel_linear_sort($lists, "|-");
		return ["code" => \app\system\model\Code::success, "data" => $data];
	}
	public static function add($options)
	{
		\think\Db::startTrans();
		try {
			if ($options["type"] == 1) {
				$level = self::getParent($options["pid"]);
				if ($level >= 4) {
					return ["code" => \app\system\model\Code::fail, "msg" => "菜单不允许超出三级"];
				}
			}
			if ($options["type"] == 2) {
				$uri_exist = \think\Db::name("system_admin_menu")->where(["uri" => $options["uri"]])->find();
				if (!empty($uri_exist)) {
					return ["code" => \app\system\model\Code::fail, "msg" => "该权限已经存在"];
				}
			}
			$data = ["pid" => $options["pid"], "type" => $options["type"], "name" => $options["name"], "icon" => empty($options["icon"]) ? "" : $options["icon"], "sort" => $options["sort"], "uri" => empty($options["uri"]) ? "" : $options["uri"], "disable" => $options["disable"], "show" => $options["show"], "create_time" => time()];
			if (!empty($options["system"])) {
				$data["system"] = 1;
			}
			\think\Db::name("system_admin_menu")->insert($data);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function edit($options)
	{
		\think\Db::startTrans();
		try {
			if ($options["type"] == 1) {
				$level = self::getParent($options["pid"]);
				if ($level >= 4) {
					return ["code" => \app\system\model\Code::fail, "msg" => "菜单不允许超出三级"];
				}
			}
			if ($options["type"] == 2) {
				$uri_exist = \think\Db::name("system_admin_menu")->where(["uri" => $options["uri"]])->find();
				if (!empty($uri_exist)) {
					return ["code" => \app\system\model\Code::fail, "msg" => "该权限已经存在"];
				}
			}
			$data = ["pid" => $options["pid"], "type" => $options["type"], "name" => $options["name"], "icon" => empty($options["icon"]) ? "" : $options["icon"], "sort" => $options["sort"], "uri" => empty($options["uri"]) ? "" : $options["uri"], "disable" => $options["disable"], "show" => $options["show"], "update_time" => time()];
			if (!empty($options["system"])) {
				$data["system"] = 1;
			}
			\think\Db::name("system_admin_menu")->where(["id" => $options["id"], "system" => 0])->update($data);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function status($options)
	{
		\think\Db::startTrans();
		try {
			$data = ["disable" => $options["disable"], "update_time" => time()];
			$set = \think\Db::name("system_admin_menu")->where(["id" => $options["id"], "system" => 0])->update($data);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function show($options)
	{
		\think\Db::startTrans();
		try {
			$data = ["show" => $options["show"], "update_time" => time()];
			$set = \think\Db::name("system_admin_menu")->where(["id" => $options["id"], "system" => 0])->update($data);
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function del($options)
	{
		\think\Db::startTrans();
		try {
			$lists = \think\Db::name("system_admin_menu")->field(["id", "pid", "name", "sort", "icon", "disable", "show"])->select();
			$del_ids = $options["ids"];
			foreach ($options["ids"] as $id) {
				$temp = self::getChildIds($lists, $id);
				$del_ids = array_merge($del_ids, $temp);
			}
			$del = \think\Db::name("system_admin_menu")->where("id", "in", $del_ids)->where(["system" => 0])->delete();
			\think\Db::name("system_admin_role_auth")->where("menu_auth_id", "in", $del_ids)->delete();
			\think\Db::commit();
			return ["code" => \app\system\model\Code::success];
		} catch (\Exception $e) {
			\think\Db::rollback();
			return ["code" => \app\system\model\Code::error, "msg" => $e->getMessage()];
		}
	}
	public static function getChildIds($lists, $id)
	{
		$ids = [];
		foreach ($lists as $key => $row) {
			if ($row["pid"] == $id) {
				$ids[] = $row["id"];
				$child_ids = self::getChildIds($lists, $row["id"]);
				foreach ($child_ids as $child_id) {
					$ids[] = $child_id;
				}
			}
		}
		return $ids;
	}
	public static function getParent($pid)
	{
		static $count = 0;
		$auth = \think\Db::name("system_admin_menu")->where(["id" => $pid])->find();
		if ($auth) {
			$count += 1;
			if ($count < 3) {
				self::getParent($auth["pid"]);
			}
			return $count;
		}
		return $count;
	}
	public static function getMenuTree($admin_info)
	{
		try {
			$lists = \think\Db::name("system_admin_menu")->where(["type" => 1, "show" => 0])->order(["sort" => "desc"])->select();
			$lists = (new \app\common\system\System())->admin_menu_plug_filter($lists, "system_menu_id", true);
			$none_auth = AuthService::getRoleNoneAuthIds($admin_info["role_id"]);
			$lists = self::setRoleMenu($none_auth, $lists);
			return linear_to_tree($lists);
		} catch (\Exception $e) {
			return [];
		}
	}
	public static function getMenuHtml($role_id)
	{
		$lists = \think\Db::name("system_admin_menu")->where(["type" => 1, "show" => 0])->order(["sort" => "desc"])->select();
		$none_auth = AuthService::getRoleNoneAuthIds($role_id);
		$lists = self::setRoleMenu($none_auth, $lists);
		return self::createHtml(linear_to_tree($lists), true);
	}
	public static function menuIsUpdate($menu, $role_id)
	{
		$new_meu_md5 = md5($menu);
		$menu_md5 = \think\facade\Cache::get("menu_md5_role_id" . $role_id);
		if ($menu_md5 == $new_meu_md5) {
			return false;
		}
		\think\facade\Cache::set("menu_md5", $new_meu_md5);
		return true;
	}
	private static function setRoleMenu(&$none_auth, $lists)
	{
		foreach ($lists as $k => $v) {
			if (in_array($v["id"], $none_auth)) {
				unset($lists[$k]);
			}
		}
		return array_values($lists);
	}
	protected static function createHtml($menu, $max = false)
	{
		if ($max) {
			$html = "";
			$choose_class = "layui-this";
			foreach ($menu as $k => $v) {
				$sub = isset($v["sub"]) ? $v["sub"] : [];
				if ($sub) {
					$html .= "<li data-name=\"set\" class=\"layui-nav-item\"><a href=\"javascript:;\" lay-tips=\"" . $v["name"] . "\" lay-direction=\"2\"><i class=\"layui-icon " . $v["icon"] . "\"></i><cite>" . $v["name"] . "</cite></a><dl class=\"layui-nav-child\">";
					$html .= self::createHtml($sub);
					$html .= "</li>";
				} else {
					$html .= "<li data-name=\"set\" class=\"layui-nav-item " . $choose_class . "\"><a href=\"javascript:;\" lay-href=\"" . self::uri($v["uri"]) . "\" lay-tips=\"" . $v["name"] . "\" lay-direction=\"2\"><i class=\"layui-icon " . $v["icon"] . "\"></i><cite>" . $v["name"] . "</cite></a>";
					$html .= "</dl></li>";
				}
				$choose_class = "";
			}
			return $html;
		}
		$html = "";
		foreach ($menu as $k => $v) {
			$sub = isset($v["sub"]) ? $v["sub"] : [];
			if ($sub) {
				$html .= "<dd class=\"layui-nav-itemed\"><a href=\"javascript:;\">" . $v["name"] . "<i class=\"layui-icon " . $v["icon"] . "\"></i></a><dl class=\"layui-nav-child\">";
				$html .= self::createHtml($sub);
				$html .= "</dl></dd>";
			} else {
				$html .= "<dd><a href=\"javascript:;\" lay-href=\"" . self::uri($v["uri"]) . "\"><i class=\"layui-icon " . $v["icon"] . "\"></i>" . $v["name"] . "</a></dd>";
			}
		}
		return $html;
	}
	private static function uri($uri)
	{
		if ($uri) {
			return \think\facade\Url::build($uri);
		}
		return "";
	}
}